/*
 * This source file is part of ARK
 * For the latest info, see https://github.com/ArkNX
 *
 * Copyright (c) 2013-2019 ArkNX authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"),
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#pragma once

#include "proto/AFProtoCPP.hpp"
#include "base/AFBus.hpp"
#include "AFINet.hpp"

namespace ark {

class AFServerData
{
public:
    void Init(const AFGUID& conn_id, const AFMsg::msg_ss_server_report& data)
    {
        conn_id_ = conn_id;
        server_info_ = data;
    }

    AFGUID conn_id_{0};
    AFMsg::msg_ss_server_report server_info_;
};

class AFClientConnectionData
{
public:
    int32_t logic_state_{0};
    int32_t game_id_{0};
    AFGUID actor_id_{0};
    AFGUID conn_id_{0};
    std::string account_{};
};

class AFINetServerService
{
public:
    virtual ~AFINetServerService() = default;

    template<typename BaseType>
    bool RegMsgCallback(const int msg_id, BaseType* pBase, void (BaseType::*handleRecv)(const AFNetMsg*, const int64_t))
    {
        NET_MSG_FUNCTOR functor = std::bind(handleRecv, pBase, std::placeholders::_1, std::placeholders::_2);
        return RegMsgCallback(msg_id, std::move(functor));
    }

    template<typename BaseType>
    bool RegForwardMsgCallback(BaseType* pBase, void (BaseType::*handleRecv)(const AFNetMsg*, const int64_t))
    {
        NET_MSG_FUNCTOR functor = std::bind(handleRecv, pBase, std::placeholders::_1, std::placeholders::_2);
        return RegForwardMsgCallback(std::move(functor));
    }

    template<typename BaseType>
    bool RegNetEventCallback(BaseType* pBase, void (BaseType::*handler)(const AFNetEvent*))
    {
        NET_EVENT_FUNCTOR functor = std::bind(handler, pBase, std::placeholders::_1);
        return RegNetEventCallback(std::move(functor));
    }

    virtual bool Start(const AFHeadLength len, const int bus_id, const AFEndpoint& ep, const uint8_t thread_count, const uint32_t max_connection) = 0;
    virtual bool Update() = 0;

    // virtual bool SendBroadcastMsg(const int nMsgID, const std::string& msg, const AFGUID& player_id) = 0;
    // virtual bool SendBroadcastPBMsg(const uint16_t msg_id, const google::protobuf::Message& pb_msg, const AFGUID&
    // player_id) = 0; virtual bool SendPBMsg(const uint16_t msg_id, const google::protobuf::Message& pb_msg, const
    // AFGUID& connect_id, const AFGUID& player_id, const std::vector<AFGUID>* target_list = nullptr) = 0; virtual bool
    // SendMsg(const uint16_t msg_id, const std::string& data, const AFGUID& connect_id, const AFGUID& player_id, const
    // std::vector<AFGUID>* target_list = nullptr) = 0;
    virtual std::shared_ptr<AFINet> GetNet() = 0;

    virtual bool RegMsgCallback(const int msg_id, NET_MSG_FUNCTOR&& cb) = 0;
    virtual bool RegForwardMsgCallback(NET_MSG_FUNCTOR&& cb) = 0;
    virtual bool RegNetEventCallback(NET_EVENT_FUNCTOR&& cb) = 0;
};

} // namespace ark
